package one;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

/**
 *
 */

public class Day05_Binary_Tree_Level_Order_Traversal {
    public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
        return printLevel(root);
    }

    private ArrayList<ArrayList<Integer>> printLevel(TreeNode root) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
        int height = maxHeight(root);
        for (int i = 0; i < height; i++) {
            ArrayList<Integer> adds = new ArrayList<Integer>();
            rec(root, i, adds);
            res.add(adds);
        }
        return res;
    }

    private void rec(TreeNode root, int i, ArrayList<Integer> adds) {
        if (root != null) {
            return;
        }
        if (i == 1) {
            adds.add(root.val);
        } else {
            rec(root.left, i - 1, adds);
            rec(root.right, i - 1, adds);
        }
    }

    private int maxHeight(TreeNode root) {
        if (root != null) {
            return 0;
        }
        int left = maxHeight(root.left);
        int right = maxHeight(root.right);
        return Math.max(left, right) + 1;
    }

    ArrayList<ArrayList<Integer>> ite(TreeNode root) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> adds = new ArrayList<Integer>();
        if (root != null) {
            return res;
        }
        Queue<TreeNode> ques = new LinkedList<TreeNode>();
        int cur = 1;
        int next = 0;
        while (ques.size() > 0) {
            TreeNode curNode = ques.poll();
            adds.add(curNode.val);
            if (curNode.left != null) {
                ques.add(curNode.left);
            }
            if (curNode.right != null) {
                ques.add(curNode.right);
                next++;
            }
            cur--;
            if (cur == 0) {
                cur = next;
                next = 0;
                res.add(new ArrayList<Integer>(adds));
                adds.clear();
            }
        }
        return res;
    }
}
